package lib.bone.admin.controller.system;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Validator;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lib.bone.admin.anno.WebLog;
import lib.bone.admin.constant.MethodTypeConst;
import lib.bone.common.constant.ResponseCodeConst;
import lib.bone.common.core.domain.ResponseDTO;
import lib.bone.system.dao.SysDeptDAO;
import lib.bone.system.domain.dto.dept.DeptAddDTO;
import lib.bone.system.domain.dto.dept.DeptUpdateDTO;
import lib.bone.system.domain.entity.SysDept;
import lib.bone.system.domain.entity.SysUser;
import lib.bone.system.service.SysDeptService;
import lib.bone.system.service.SysUserService;
import lib.bone.system.service.impl.SysDeptServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 部门管理控制器
 * @Author : kindear
 * @Date : 2021-11-28
 */
@Slf4j
@RestController
@RequestMapping("system")
@Api(tags = "系统部门管理")
public class SysDeptController {

    @Autowired
    SysDeptService sysDeptService;

    @Autowired
    SysUserService sysUserService;

    @WebLog(module = "bone-system")
    @PostMapping(value = {"departments","depts"})
    @ApiOperation(value = "新建部门",notes = "")
    @SaCheckPermission(value = "system_dept:add",orRole = "admin")
    public ResponseDTO<SysDept> saveDept(@RequestBody @Validated DeptAddDTO deptAddDTO){
        /* 初始化构建 **/
        SysDept sysDept = new SysDept();
        BeanUtil.copyProperties(deptAddDTO,sysDept, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        /*
          如果是null 赋值为0
         */
        if(Validator.isEmpty(deptAddDTO.getParentId())){
            deptAddDTO.setParentId(0L);
        }
        Optional<SysDept> parentOp = sysDeptService.getById(deptAddDTO.getParentId());

        if(parentOp.isPresent()){
            /* 设置祖先 和 父部门 --ignore **/
            sysDept.setParent(parentOp.get());
            SysDept parent = new SysDept();
            BeanUtil.copyProperties(parentOp.get(),parent);
            List<Long> ancestors = parent.getAncestors();
            ancestors.add(deptAddDTO.getParentId());
            sysDept.setAncestors(ancestors);

        }else {
            List<Long> ancestors = new ArrayList<>();
            ancestors.add(0L);
            sysDept.setAncestors(ancestors);
        }
        return ResponseDTO.succData(sysDeptService.saveOne(sysDept));
        //return sysDeptService.saveDept(deptAddDTO);
    }

    /**
     * @TODO 需要阻止递归依赖的情况发生
     * 部门信息修改
     */
    @WebLog(module = "bone-system",operate = MethodTypeConst.UPDATE)
    @PutMapping(value = {"depts","departments"})
    @ApiOperation(value = "更新部门",notes = "")
    @SaCheckPermission(value = "system_dept:update",orRole = "admin")
    public ResponseDTO updateDept(@RequestBody @Validated DeptUpdateDTO deptUpdateDTO){
        Optional<SysDept> sysDeptOp = sysDeptService.getById(deptUpdateDTO.getId());
        if(!sysDeptOp.isPresent())
            return ResponseDTO.wrap(ResponseCodeConst.NOT_FOUND);
        SysDept sysDept = sysDeptOp.get();
        BeanUtil.copyProperties(deptUpdateDTO,sysDept, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        return ResponseDTO.succData(sysDeptService.updateOne(sysDept));
    }

    /**
     * 获取全部部门信息 -- 不展开
     * @return
     */
    @GetMapping(value = {"depts","departments"})
    @ApiOperation(value = "获取全部部门",notes = "")
    public ResponseDTO getDepts(){
        List<SysDept> sysDepts = sysDeptService.findByParent(null);
        return ResponseDTO.succData(sysDepts);
    }

    /**
     * 获取部门下所有用户信息
     * @param deptId
     * @return
     */
    @GetMapping("depts/{deptId}/users")
    @ApiOperation(value = "获取部门下所有用户",notes = "")
    public ResponseDTO getDeptUsers(@PathVariable("deptId") Long deptId){
        return ResponseDTO.succData(sysUserService.findByDept(deptId));
    }

    @GetMapping(value = {"depts/{id}","departments/{id}"})
    @ApiOperation(value = "获取单个部门",notes = "传入部门ID，获取部门信息")
    public ResponseDTO getOneDept(@PathVariable("id") Long id){
        Optional<SysDept> sysDeptOp = sysDeptService.getById(id);
        if(sysDeptOp.isPresent()){
            return ResponseDTO.succData(sysDeptOp.get());
        }else {
            return ResponseDTO.wrap(ResponseCodeConst.NOT_FOUND,"ID:["+id+"]对应部门不存在");
        }
    }

    @WebLog(module = "bone-system",operate = MethodTypeConst.DELETE)
    @DeleteMapping(value = {"depts/{id}","departments/{id}"})
    @ApiOperation(value = "删除单个部门",notes = "传入部门ID，删除部门信息")
    @SaCheckPermission(value = "system_dept:delete",orRole = "admin")
    public ResponseDTO deleteOneDept(@PathVariable("id") Long id){
        return sysDeptService.deleteById(id);
    }

    /** 构建部门选择树 **/
    @GetMapping(value = "depts/tree")
    @ApiOperation(value = "部门选择树",notes = "获取部门选择树")
    public ResponseDTO buildDeptTree(){
        log.info("构建部门树");
        //查询父部门为空状态，即为头部节点
        List<SysDept> sysDepts = sysDeptService.findByParent(null);
        return ResponseDTO.succData(sysDeptService.buildDeptTree(sysDepts));
    }


}
